<?
/*! \brief Dijit form creator for any web service
 * 
 */
class ServiceDojoForm extends Zend_Dojo_Form
{
	protected $_node, $_method, $_decor;
	
	/*! \brief constructor
	 * 
	 * \param $node the URL of this node
	 * \param $method service name 
	 */
	public function __construct($node, $method)
	{
		Zend_Dojo::enableForm($this);
		$this->_node = $node;	
		$this->_method = $method;
		
		$this->setAction('')
			 ->setMethod('post')
			 ->setAttrib('id', 'serviceForm')
			 ->setAttrib('enctype', 'multipart/form-data');	
		
		$this->setDecorators(array(
		    'FormElements',
		    array('ContentPane', array(
		        'id'          => 'contentPane',
		        'style'       => 'width: -1; height: -1; margin-top: 20px; margin-left: 20px',
		        'dijitParams' => array(
		            'contentPane' => 'top'
		        ),
		    )),
		    'DijitForm',
		));
		
		$this->buildForm();
		$this->addSubmitButton();
	}
	
	/*! \brief Build the Dijit Form
	 * 
	 * Using the internalized service XML, iterate over all items (e.g., 
	 * operands, options, arguments) and build an array of elements capable of 
	 * being added with Zend_Dojo_Form::addElement().
	 */
	public function buildForm()
	{	
		$xml = $this->getServiceXml();
		$i = 0;
				
		// INPUTS
		if(isset($xml->inputs))
		{
			foreach ($xml->inputs->input as $input)
			{	
				//no label for operands		
				$pos = strpos((string)$input->qualifier, 'operand');
				if($pos === false)
					$label = (string)$input->qualifier;
				else
					$label = '(operand)';
								
				switch($input->type)
				{
					case 'file':
						$elements[++$i] = array('type' => 'File',
								  		'name' => (string)$input->qualifier,
								  		'label' => (string)$input->description,
								  		'desc' => (string)$input->description,
										'require' =>  (string)$input->required,
								  		'value' => (string)$input->value);
						break;
						
					case 'argument':
						if($input->encrypt)
							$type = 'PasswordTextBox';
						else
							$type = 'ValidationTextBox';
						
						$elements[++$i] = array('type' => $type,
										'name' => str_replace("-","",$input->qualifier),
										'label' => (string)$input->description,
										'desc' => (string)$input->description,
										'require' => (string)$input->required,
										'value' => (string)$input->value);
						break;
					
					case 'flag':
						$elements[++$i] = array('type' => 'CheckBox',
										'name' => str_replace("-", "", $input->qualifier),
										'label' => (string)$input->description,
										'desc' => (string)$input->description,
										'enabled' => (string)$input->enabled);
						break;
				}
			}
		}
		
		// HIDDEN: node and method
		$elements[++$i] = array('type' => 'hidden',
								'name' => 'node',
								'value' => $this->_node);
		
		$elements[++$i] = array('type' => 'hidden',
								'name' => 'method',
								'value' => $this->_method);
		
		$this->addElements($elements);
	}
	
	/*! \brief Add submit button to this form
	 * 
	 */
	public function addSubmitButton()
	{
		$element[0] = array('type' => 'SubmitButton',
							'name' => 'Run',
							'label' => 'Run');
						
		$this->addElements($element);
	}
	
	/*! \brief Add an array of elements to this form.
	 * 
	 * Each element in the array should have acceptable fields for 
	 * Zend_Dojo_Form::addElement()
	 * 
	 * \param $elements array of elements 
	 */
	public function addElements($elementsArray)
	{
		foreach ($elementsArray as $element)
		{
			//Required
			($element['require'] == "true") ? $element['require'] = true : 
				$element['require'] = false;
			
			//Checked
			($element['enabled'] == "true") ? $checked = true : $checked = false;
				
			switch ($element['type'])
			{		
				case 'CheckBox':
					$this->addElement($element['type'], $element['name'], 
						array(	'label' => $element['desc'], 
								'checked' => $checked)); //attribs
					break;
				case 'ValidationTextBox':
					$this->addElement($element['type'], $element['name'], 
						array(	'label' => $element['label'], 
								'required' => $element['require'], 
								'invalidMessage' => 'Required',
								'value' => $element['value'])); //attribs
					break;
				case 'PasswordTextBox':
					$this->addElement($element['type'], $element['name'], 
						array(	'label' => $element['label'], 
								'required' => $element['require'], 
								'invalidMessage' => 'Required')); //attribs
					break;
				case 'File':
					$this->addElement($element['type'], $element['name'], 
						array(	'label' => $element['label'], 
								'required' => true)); //attribs
					break;
				case 'SubmitButton':
					$this->addElement($element['type'], $element['name'], 
						array('label' => $element['label'])); //attribs
					break;
				case 'hidden':
					$this->addElement($element['type'], $element['name'], 
						array(	'value' => $element['value'], 
								'style' => 'display: none;')); //attribs
					break;
			}
			
			$this->decorate($this->getElement($element['name']), $element['desc']);
		}			
	}
	
	/*! \brief Just removes any decorator from hidden elements
	 */
	public function decorate($element, $desc)
	{		
		if($element->getType() == 'Zend_Form_Element_Hidden')
			$element->removeDecorator("Label");
	}

	/*! \brief Returns the service XML internalized within this object.
	 * 
	 * \return XML object
	 */
	public function getServiceXml()
	{
		//Get the XML
		$result = file_get_contents($this->_node.$this->_method);
		$xml = new XML();
		
		//Might be a one shot web service: no arguments/flags or inputs
		if(!$xml->setStringXml($result))
			return false;
		
		return $xml->getSimple();
	}
}